import nimx/keyboard
import tables, hashes
import x11/[x, keysym]

# proc hash(s: KeySym): Hash {.inline.} = hash(culong(s))

const virtualKeyMapping: Table[KeySym, VirtualKey] = {
  XK_Escape:       VirtualKey.Escape,
  XK_1:        VirtualKey.One,
  XK_2:        VirtualKey.Two,
  XK_3:        VirtualKey.Three,
  XK_4:        VirtualKey.Four,
  XK_5:        VirtualKey.Five,
  XK_6:        VirtualKey.Six,
  XK_7:        VirtualKey.Seven,
  XK_8:        VirtualKey.Eight,
  XK_9:        VirtualKey.Nine,
  XK_0:        VirtualKey.Zero,
  XK_minus:      VirtualKey.Minus,
  XK_equal:       VirtualKey.Equals,
  XK_BackSpace:    VirtualKey.Backspace,
  XK_TAB:        VirtualKey.Tab,
  XK_Q:        VirtualKey.Q,
  XK_W:        VirtualKey.W,
  XK_E:        VirtualKey.E,
  XK_R:        VirtualKey.R,
  XK_T:        VirtualKey.T,
  XK_Y:        VirtualKey.Y,
  XK_U:        VirtualKey.U,
  XK_I:        VirtualKey.I,
  XK_O:        VirtualKey.O,
  XK_P:        VirtualKey.P,
  XK_bracketleft:    VirtualKey.LeftBracket,
  XK_bracketright:   VirtualKey.RightBracket,
  XK_Return:       VirtualKey.Return,
  XK_Control_L:    VirtualKey.LeftControl,
  XK_A:        VirtualKey.A,
  XK_S:        VirtualKey.S,
  XK_D:        VirtualKey.D,
  XK_F:        VirtualKey.F,
  XK_G:        VirtualKey.G,
  XK_H:        VirtualKey.H,
  XK_J:        VirtualKey.J,
  XK_K:        VirtualKey.K,
  XK_L:        VirtualKey.L,
  XK_SEMICOLON:    VirtualKey.Semicolon,
  XK_APOSTROPHE:     VirtualKey.Apostrophe,
  XK_GRAVE:      VirtualKey.Backtick,
  XK_Shift_L:      VirtualKey.LeftShift,
  XK_BACKSLASH:    VirtualKey.BackSlash,
  XK_Z:        VirtualKey.Z,
  XK_X:        VirtualKey.X,
  XK_C:        VirtualKey.C,
  XK_V:        VirtualKey.V,
  XK_B:        VirtualKey.B,
  XK_N:        VirtualKey.N,
  XK_M:        VirtualKey.M,
  XK_COMMA:      VirtualKey.Comma,
  XK_PERIOD:       VirtualKey.Period,
  XK_SLASH:      VirtualKey.Slash,
  XK_Shift_R:      VirtualKey.RightShift,
  XK_KP_MULTIPLY:    VirtualKey.KeypadMultiply,
  XK_Alt_L:      VirtualKey.LeftAlt,
  XK_SPACE:      VirtualKey.Space,
  XK_CAPSLOCK:     VirtualKey.CapsLock,
  XK_F1:         VirtualKey.F1,
  XK_F2:         VirtualKey.F2,
  XK_F3:         VirtualKey.F3,
  XK_F4:         VirtualKey.F4,
  XK_F5:         VirtualKey.F5,
  XK_F6:         VirtualKey.F6,
  XK_F7:         VirtualKey.F7,
  XK_F8:         VirtualKey.F8,
  XK_F9:         VirtualKey.F9,
  XK_F10:        VirtualKey.F10,
  XK_Num_Lock:     VirtualKey.NumLock,
  XK_Scroll_Lock:    VirtualKey.ScrollLock,
  XK_KP_7:       VirtualKey.Keypad7,
  XK_KP_8:       VirtualKey.Keypad8,
  XK_KP_9:       VirtualKey.Keypad9,
  XK_KP_Subtract:    VirtualKey.KeypadMinus,
  XK_KP_4:       VirtualKey.Keypad4,
  XK_KP_5:       VirtualKey.Keypad5,
  XK_KP_6:       VirtualKey.Keypad6,
  XK_KP_Add:       VirtualKey.KeypadPlus,
  XK_KP_1:       VirtualKey.Keypad1,
  XK_KP_2:       VirtualKey.Keypad2,
  XK_KP_3:       VirtualKey.Keypad3,
  XK_KP_0:       VirtualKey.Keypad0,
  XK_KP_Decimal:     VirtualKey.KeypadPeriod,
  # XK_NONUSBACKSLASH:   VirtualKey.NonUSBackSlash,
  XK_F11:        VirtualKey.F11,
  XK_F12:        VirtualKey.F12,
  #0:         VirtualKey.International1, # -
  #0:         VirtualKey.Lang3, # -
  #0:         VirtualKey.Lang4, # -
  #0:         VirtualKey.International4, # -
  #0:         VirtualKey.International2, # -
  #0:         VirtualKey.International5, # -
  #0:         VirtualKey.International6, # -
  XK_KP_ENTER:     VirtualKey.KeypadEnter,
  XK_Control_R:    VirtualKey.RightControl,
  XK_KP_DIVIDE:    VirtualKey.KeypadDivide,
  XK_3270_PrintScreen: VirtualKey.PrintScreen,
  XK_Alt_R:      VirtualKey.RightAlt,
  XK_HOME:       VirtualKey.Home,
  XK_UP:         VirtualKey.Up,
  XK_PAGEUP:       VirtualKey.PageUp,
  XK_LEFT:       VirtualKey.Left,
  XK_RIGHT:      VirtualKey.Right,
  XK_END:        VirtualKey.End,
  XK_DOWN:       VirtualKey.Down,
  XK_PAGEDOWN:     VirtualKey.PageDown,
  XK_INSERT:       VirtualKey.Insert,
  XK_DELETE:       VirtualKey.Delete,
  # XK_MUTE:       VirtualKey.Mute,
  # XK_VOLUMEDOWN:     VirtualKey.VolumeDown,
  # XK_VOLUMEUP:     VirtualKey.VolumeUp,
  # XK_POWER:      VirtualKey.Power,
  XK_KP_EQUAL:     VirtualKey.KeypadEquals,
  # XK_KP_PLUSMINUS:   VirtualKey.KeypadPlusMinus,
  XK_PAUSE:      VirtualKey.Pause,
  XK_KP_Separator:   VirtualKey.KeypadComma,
  #0:         VirtualKey.Lang1, # -
  #0:         VirtualKey.Lang2, # -
  XK_Meta_L:       VirtualKey.LeftGUI,
  XK_Super_L:      VirtualKey.LeftGUI,
  XK_Meta_R:       VirtualKey.RightGUI,
  XK_Super_R:      VirtualKey.RightGUI,
  # XK_Cancel:       VirtualKey.Stop,
  XK_Redo:       VirtualKey.Again,
  XK_UNDO:       VirtualKey.Undo,
  # XK_COPY:       VirtualKey.Copy,
  # XK_PASTE:      VirtualKey.Paste,
  XK_FIND:       VirtualKey.Find,
  # XK_CUT:        VirtualKey.Cut,
  XK_HELP:       VirtualKey.Help,
  XK_MENU:       VirtualKey.Menu,
  # XK_CALCULATOR:     VirtualKey.Calculator,
  # XK_SLEEP:      VirtualKey.Sleep,
  # XK_MAIL:       VirtualKey.Mail,
  # XK_AC_BOOKMARKS:   VirtualKey.AcBookmarks,
  # XK_COMPUTER:     VirtualKey.Computer,
  # XK_AC_BACK:      VirtualKey.AcBack,
  # XK_AC_FORWARD:     VirtualKey.AcForward,
  # XK_EJECT:      VirtualKey.Eject,
  # XK_AUDIONEXT:    VirtualKey.AudioNext,
  # XK_AUDIOPLAY:    VirtualKey.AudioPlay,
  # XK_AUDIOPREV:    VirtualKey.AudioPrev,
  # XK_AC_HOME:      VirtualKey.AcHome,
  # XK_AC_REFRESH:     VirtualKey.AcRefresh,
  # XK_KP_LEFTPAREN:   VirtualKey.KeypadLeftPar,
  # XK_KP_RIGHTPAREN:  VirtualKey.KeypadRightPar,
  XK_F13:        VirtualKey.F13,
  XK_F14:        VirtualKey.F14,
  XK_F15:        VirtualKey.F15,
  XK_F16:        VirtualKey.F16,
  XK_F17:        VirtualKey.F17,
  XK_F18:        VirtualKey.F18,
  XK_F19:        VirtualKey.F19,
  XK_F20:        VirtualKey.F20,
  XK_F21:        VirtualKey.F21,
  XK_F22:        VirtualKey.F22,
  XK_F23:        VirtualKey.F23,
  XK_F24:        VirtualKey.F24,
  # XK_AC_SEARCH:    VirtualKey.AcSearch,
  # XK_ALTERASE:     VirtualKey.AltErase,
  XK_CANCEL:       VirtualKey.Stop,
  # XK_BRIGHTNESSDOWN:   VirtualKey.BrightnessDown,
  # XK_BRIGHTNESSUP:   VirtualKey.BrightnessUp,
  # XK_DISPLAYSWITCH:  VirtualKey.DisplaySwitch,
  # XK_KBDILLUMTOGGLE:   VirtualKey.IlluminateToggle,
  # XK_KBDILLUMDOWN:   VirtualKey.IlluminateDown,
  # XK_KBDILLUMUP:     VirtualKey.IlluminateUp
  XKc_A:         VirtualKey.A,
  XKc_B:         VirtualKey.B,
  XKc_C:         VirtualKey.C,
  XKc_D:         VirtualKey.D,
  XKc_E:         VirtualKey.E,
  XKc_F:         VirtualKey.F,
  XKc_G:         VirtualKey.G,
  XKc_H:         VirtualKey.H,
  XKc_I:         VirtualKey.I,
  XKc_J:         VirtualKey.J,
  XKc_K:         VirtualKey.K,
  XKc_L:         VirtualKey.L,
  XKc_M:         VirtualKey.M,
  XKc_N:         VirtualKey.N,
  XKc_O:         VirtualKey.O,
  XKc_P:         VirtualKey.P,
  XKc_Q:         VirtualKey.Q,
  XKc_R:         VirtualKey.R,
  XKc_S:         VirtualKey.S,
  XKc_T:         VirtualKey.T,
  XKc_U:         VirtualKey.U,
  XKc_V:         VirtualKey.V,
  XKc_W:         VirtualKey.W,
  XKc_X:         VirtualKey.X,
  XKc_Y:         VirtualKey.Y,
  XKc_Z:         VirtualKey.Z,
}.toTable()

template virtualKeyFromNative*(kc: KeySym): VirtualKey = virtualKeyMapping.getOrDefault(kc)
